
#ifndef __DATA_TYPE_INCLUDE_H
#define __DATA_TYPE_INCLUDE_H


#include <vector>
#include <map>
#include <string>
#include <fstream>
#include <sstream>
#include <iostream>
#include <hash_set>
using namespace std;

#include <osg/Vec4>
#include "GeomStructure.h"

struct BoxelIndex
{
	unsigned long	x, y, z;

	inline BoxelIndex() {}
	inline BoxelIndex( unsigned long nX, unsigned long nY, unsigned long nZ ) : x( nX ), y( nY ), z( nZ ) {}
	inline void LocateVoxelPosition( const PT3D& bboxMin, const PT3D& bxlSize, PT3D& bxlPosition )
	{
		bxlPosition.x = bboxMin.x + ( x - 1 ) * bxlSize.x;
		bxlPosition.y = bboxMin.y + ( y - 1 ) * bxlSize.y;
		bxlPosition.z = bboxMin.z + ( z - 1 ) * bxlSize.z;
	}

	inline string FromVoxelIndexToKeyString() { stringstream ss; ss << x << "_" << y << "_" << z; ; return ss.str(); }
	static inline bool FromKeyStringToVxlIndex( const char* lpszKey, BoxelIndex& vxlIdx )
	{
		string strKey( lpszKey );
		if( strKey.empty() )
			return false;

		size_t fst_pos = strKey.find_first_of( '_' );
		size_t scd_pos = strKey.find_first_of( '_', fst_pos + 1 );
		if( fst_pos == string::npos || scd_pos == string::npos )
			return false;

		vxlIdx.x = atol( string( strKey.begin(), strKey.begin() + fst_pos ).c_str() );
		vxlIdx.y = atol( string( strKey.begin() + fst_pos + 1, strKey.begin() + scd_pos ).c_str() );
		vxlIdx.z = atol( string( strKey.begin() + scd_pos + 1, strKey.end() ).c_str() );
		return true;
	}
};
//
//struct FrustumParam
//{
//	PT3D	fruPeak;
//	PT3D	fruDir;
//	double	dHorAngle;
//	double	dVerAngle;
//	double	dFruHeight;
//
//	FrustumParam() {}
//	FrustumParam( const PT3D& fruPeakT, const PT3D& fruDirT, double dHorAngleT, double dVerAngleT, double dFruHeightT )
//		: fruPeak( fruPeakT )
//		, fruDir( fruDirT )
//		, dHorAngle( dHorAngleT )
//		, dVerAngle( dVerAngleT )
//		, dFruHeight( dFruHeightT )
//	{
//	}
//
//	PT3D	PtCenterOnFarPlane() const
//	{
//		return PT3D( fruPeak.x + fruDir.x * dFruHeight, fruPeak.y + fruDir.y * dFruHeight, fruPeak.z + fruDir.z * dFruHeight );
//	}
//
//	/*bool operator == ( const FrustumParam& fp )
//	{
//		if( fruDir == fp.fruDir )
//			return false;
//
//		if( fp.fruDir != fruDir )
//			return false;
//	}*/
//};

enum DATA_MAP_TYPE{ DMT_XYZ = 0, DMT_YZX, DMT_ZXY, DMT_UNKNOWN };
//
//inline void RandomColor( int i, osg::Vec4& clr )
//{
//	vector<osg::Vec4> vClr;
//	vClr.push_back( osg::Vec4( 0.784f, 0.18f, 0.015f, 1.0f ) );
//	vClr.push_back( osg::Vec4( 0.870588235f, 0.643137255f, 0.011764706f, 1.0f ) );
//	vClr.push_back( osg::Vec4( 0.662745098f, 0.878431373, 0.011764706, 1.0f ) );
//	vClr.push_back( osg::Vec4( 0.011764706, 0.878431373, 0.729411765, 1.0f ) );
//	vClr.push_back( osg::Vec4( 0.478431373, 0.776470588, 0.996078431, 1.0f ) );
//	vClr.push_back( osg::Vec4( 0.725490196, 0.482352941, 0.992156863, 1.0f ) );
//	vClr.push_back( osg::Vec4( 0.988235294, 0.48627451, 0.937254902, 1.0f ) );
//	vClr.push_back( osg::Vec4( 0.607843137, 0.588235294, 0.839215686, 1.0f ) );
//	vClr.push_back( osg::Vec4( 0.384313725, 0.658823529, 0.658823529, 1.0f ) );
//	vClr.push_back( osg::Vec4( 0.650980392, 0.603921569, 0.392156863, 1.0f ) );
//
//	vClr.push_back( osg::Vec4( 1.0f, 0.0f, 0.0f, 1.0f ) );
//	vClr.push_back( osg::Vec4( 0.0f, 1.0f, 0.0f, 1.0f ) );
//	vClr.push_back( osg::Vec4( 0.0f, 0.0f, 1.0f, 1.0f ) );
//	vClr.push_back( osg::Vec4( 1.0f, 1.0f, 0.0f, 1.0f ) );
//	vClr.push_back( osg::Vec4( 1.0f, 0.0f, 1.0f, 1.0f ) );
//	vClr.push_back( osg::Vec4( 0.0f, 1.0f, 1.0f, 1.0f ) );
//	vClr.push_back( osg::Vec4( 0.5f, 0.5f, 0.5f, 1.0f ) );
//	vClr.push_back( osg::Vec4( 0.0f, 0.0f, 0.0f, 1.0f ) );
//
//	clr = vClr[ i % vClr.size() ];
//}

typedef map< int, map< int, map< int, int >>> DataMap;
typedef map<string, vector<string>>		VxlProp;

const double FruPI = 3.1415926;

inline void	BxlSetCompare( const hash_set<string>& hsSet0, const hash_set<string>& hsSet1, vector<string>& vSame, vector<string>& vDif0, vector<string>& vDif1 )
{
	map<string, int>	mapForCompare;
	hash_set<string>::const_iterator itHS0 = hsSet0.begin();
	for( ; itHS0 != hsSet0.end(); ++ itHS0 )
		mapForCompare.insert( map<string, int>::value_type( *itHS0, 1 ) );

	hash_set<string>::const_iterator itHS1 = hsSet1.begin();
	for( ; itHS1 != hsSet1.end(); ++ itHS1 )
	{
		map<string, int>::iterator itFind = mapForCompare.find( *itHS1 );
		if( itFind == mapForCompare.end() )
			mapForCompare.insert( map<string, int>::value_type( *itHS1, 0 ) );
		else
			++ mapForCompare[ *itHS1 ];
	}

	map<string, int>::iterator  itMap = mapForCompare.begin();
	for( ; itMap != mapForCompare.end(); ++ itMap )
	{
		switch( itMap->second )
		{
		case 0:
			vDif1.push_back( itMap->first );
			break;
		case 1:
			vDif0.push_back( itMap->first );
			break;
		case 2:
			vSame.push_back( itMap->first );
			break;
		default:
			break;
		}
	}
}



#endif	//__DATA_TYPE_INCLUDE_H